<?php

/**
 * Исключает влияние значения magic_quotes_gpc. Реализовано на уровне приложения
 * т.к. если PHP работает в режиме CGI, то через .htaccess его отконфигурировать
 * будет нельзя.
 *
 */
if (get_magic_quotes_gpc()) {
    array_apply_recursive($_GET, 'stripslashes');
    array_apply_recursive($_POST, 'stripslashes');
    array_apply_recursive($_COOKIE, 'stripslashes');
    array_apply_recursive($_REQUEST, 'stripslashes');
}

/**
 * Запрос приложения в режиме HTTP.
 *
 */
class Kernel_Request_Http implements Kernel_Request_Interface {

    /**
     * Массив секций красивого урла.
     *
     * @var array
     */
    private $_uri = array();

    /**
     * Значение ID, переданное в виде /foo/bar/baz/id.html
     *
     * @var integer
     */
    private $_id;

    /**
     * Конструктор.
     *
     */
    public function __construct() {
        // определяем путь страницы, исключая поддиректорию, в которой находится
        // сайт. вроде как везде работает.
        if (preg_match('/(.*?)((\d+)\.html)?$/', $this->_getRequestUri(), $matches)) {
            $uri = trim($matches[1], '/');
            $this->_uri = strlen($uri) > 0 ? explode('/', $uri) : array();
            $this->_id = isset($matches[3]) ? (int)$matches[3] : null;
        } else {
            // в принципе, это невозможно
            trigger_error('Unable to parse URI', E_USER_ERROR);
        }
    }

    /**
     * Возвращает значение ID.
     *
     * @return  integer
     */
    public function id() {
        return $this->_id;
    }

    /**
     * Возвращает, запрошена ли текущая страница по методу POST.
     *
     * @return  boolean
     */
    public function isPost() {
        return 'POST' == $_SERVER['REQUEST_METHOD'];
    }

    /**
     * Возвращает значение параметра GET.
     *
     * @param   string  $param
     * @param   mixed   $default
     * @return  mixed
     */
    public function get($param, $default = null) {
        return $this->hasGet($param, true) ? $_GET[$param] : $default;
    }

    /**
     * Возвращает значение параметра POST.
     *
     * @param   string  $param
     * @param   mixed   $default
     * @return  mixed
     */
    public function post($param, $default = null) {
        return $this->hasPost($param, true) ? $_POST[$param] : $default;
    }

    /**
     * Возвращает, передан ли указанный параметр.
     *
     * @param   string  $param
     * @param   boolean $empty
     * @return  boolean
     */
    public function has($param, $empty = false) {
        trigger_error(__METHOD__ . ' is not implemented');
    }

    /**
     * Возвращает, передан ли указанный параметр GET.
     *
     * @param   string  $param
     * @param   boolean $empty
     * @return  boolean
     */
    public function hasGet($param, $empty = false) {
        return $empty ? isset($_GET[$param]) : !empty($_GET[$param]);
    }

    /**
     * Возвращает, передан ли указанный параметр POST.
     *
     * @param   string  $param
     * @param   boolean $empty
     * @return  boolean
     */
    public function hasPost($param, $empty = false) {
        return $empty ? isset($_POST[$param]) : !empty($_POST[$param]);
    }

    /**
     * Возвращает значение параметра COOKIE.
     *
     * @param   string  $param
     * @param   mixed   $default
     * @return  mixed
     */
    public function cookie($param, $default = null) {
        return isset($_COOKIE[$param]) ? $_COOKIE[$param] : $default;
    }

    /**
     * Возвращает значение секции красивого URL с указанным индексом либо массив
     * секций, если индекс не указан.
     *
     * @param   integer $index
     * @param   mixed   $default
     * @return  mixed
     */
    public function uri($index = null, $default = null) {
        return !is_null($index)
            ? isset($this->_uri[$index])
                ? $this->_uri[$index]
                : $default
            : $this->_uri;
    }

    /**
     * Возвращает, запрошена ли текущая страница через безопасное соедниение.
     *
     * @return  boolean
     */
    public function secure() {
        return isset($_SERVER['HTTPS']);
    }

    /**
     * Возвращает полный URL текущей страницы.
     *
     * @return  string
     */
    public function url($secure = null) {
        return ((null === $secure ? $this->secure() : $secure) ? 'https' : 'http')
            . '://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
    }

    /**
     * Возвращает строку запроса текущей страницы в исходном виде.
     *
     * @return  string
     */
    public function query($delimiter = false) {
        $query = $_SERVER['QUERY_STRING'];
        return $delimiter
            ? strlen($query) > 0 ? '?' . $query : ''
            : $query;
    }

    /**
     * Возвращает значение, аналогичное $_SERVER['REQUEST_URI'], но
     * относительно корня сайта.
     *
     * @return  string
     */
    public function requestUri() {
        return substr($_SERVER['REQUEST_URI'], strlen(dirname($_SERVER['SCRIPT_NAME'])));
    }

    /**
     * Возвращает, была ли форма отправлена по кнопке с указанным наименованием.
     *
     * @param   string  $name
     * @return  mixed
     */
    public function submitted($name) {
        if (1 == func_num_args() && !is_array($name)) {
            return $this->_submitted($name);
        }
        foreach (array_values_recursive(func_get_args()) as $name) {
            if ($this->_submitted($name)) {
                return $name;
            }
        }
        return false;
    }

    /**
     * Возвращает, была ли форма отправлена по кнопке с указанным наименованием.
     *
     * @param   string  $name
     * @return  boolean
     */
    private function _submitted($name) {
        $data = $this->isPost() ? $_POST : $_GET;
        return isset($data[$name]) || isset($data[$name . '.x']) || isset($data[$name . '_x']);
    }

    /**
     * Возвращает адрес запрошенной страницы с учетом того, где находится корень
     * сайта. Предполагаем, что перенаправление всегда происходит на /index.php
     *
     * @return  string
     */
    private function _getRequestUri() {
        return substr(@$_SERVER['REDIRECT_URL'], strlen(dirname($_SERVER['SCRIPT_NAME'])));
    }
}
